36 volatile int8 *AccelCalPacketOn)
50 pFlash = (
float *) (CALIBRATION_NVM_ADDR + ACCEL_NVM_OFFSET);
51 if (*((
uint32 *) pFlash++) == 0x12345678)
55 for (i =
CHX; i <=
CHZ; i++) pthisAccelCal->
fV[i] = *(pFlash++);
56 for (i =
CHX; i <=
CHZ; i++)
57 for (j =
CHX; j <=
CHZ; j++)
58 pthisAccelCal->
finvW[i][j] = *(pFlash++);
59 for (i =
CHX; i <=
CHZ; i++)
60 for (j =
CHX; j <=
CHZ; j++)
61 pthisAccelCal->
fR0[i][j] = *(pFlash++);
67 pthisAccelCal->
fV[
CHX] = pthisAccelCal->
fV[
CHY] = pthisAccelCal->
fV[
CHZ] = 0.0F;
90 for (i =
CHX; i <=
CHZ; i++) pthisAccelBuffer->
fSumGs[i] = 0.0F;
96 for (i =
CHX; i <=
CHZ; i++)
97 pthisAccelBuffer->
fSumGs[i] += pthisAccel->
fGs[i];
105 for (i =
CHX; i <=
CHZ; i++)
108 pthisAccelBuffer->
fSumGs[i] /
138 for (i =
CHX; i <=
CHZ; i++)
139 ftmp[i] = pthisAccel->
fGs[i] - pthisAccelCal->
fV[i];
142 for (i =
CHX; i <=
CHZ; i++)
144 pthisAccel->
fGc[i] = pthisAccelCal->
finvW[i][
CHX] *
153 for (i =
CHX; i <=
CHZ; i++) ftmp[i] = pthisAccel->
fGc[i];
154 for (i =
CHX; i <=
CHZ; i++)
156 pthisAccel->
fGc[i] = pthisAccelCal->
fR0[
CHX][i] *
158 pthisAccelCal->
fR0[
CHY][i] *
160 pthisAccelCal->
fR0[
CHZ][i] *
174 uint8_t iMeasurements;
181 if (pthisAccelBuffer->
iStoreFlags & (1 << i)) iMeasurements++;
185 if (iMeasurements >= 9)
190 else if (iMeasurements >= 6)
195 else if (iMeasurements >= 4)
206 for (i =
CHX; i <=
CHZ; i++)
207 fGc0[i] = pthisAccelBuffer->
fGsStored[0][i] - pthisAccelCal->
fV[i];
249 for (i = 0; i < 4; i++)
251 pthisAccelCal->
fvecA[i] = 0.0F;
252 for (j = 0; j < 4; j++)
254 pthisAccelCal->
fmatA[i][j] = 0.0F;
273 pthisAccelCal->
fvecA[3] += ftmp;
297 pthisAccelCal->
fmatA[3][3] += 1.0F;
310 for (i = 0; i < 4; i++)
312 pfRows[i] = pthisAccelCal->
fmatA[i];
318 for (i = 0; i < 4; i++)
320 pthisAccelCal->
fvecB[i] = 0.0F;
321 for (j = 0; j < 4; j++)
323 pthisAccelCal->
fvecB[i] += pthisAccelCal->
fmatA[i][j] * pthisAccelCal->
fvecA[j];
333 ftmp = 1.0F / sqrtf(fabsf(pthisAccelCal->
fvecB[3] + pthisAccelCal->
fV[
CHX] *
334 pthisAccelCal->
fV[
CHX] + pthisAccelCal->
fV[
CHY] *
335 pthisAccelCal->
fV[
CHY] + pthisAccelCal->
fV[
CHZ] *
336 pthisAccelCal->
fV[
CHZ]));
360 for (i = 0; i < 7; i++)
361 for (j = i; j < 7; j++) pthisAccelCal->
fmatA[i][j] = 0.0F;
364 pthisAccelCal->
fvecA[6] = 1.0F;
381 for (m = 0; m < 7; m++)
382 for (n = m; n < 7; n++)
383 pthisAccelCal->
fmatA[m][n] += pthisAccelCal->
fvecA[m] * pthisAccelCal->
fvecA[n];
388 for (m = 1; m < 7; m++)
389 for (n = 0; n < m; n++)
390 pthisAccelCal->
fmatA[m][n] = pthisAccelCal->
fmatA[n][m];
394 pthisAccelCal->
fmatB, 7);
398 for (i = 1; i < 7; i++)
399 if (pthisAccelCal->
fvecA[i] < pthisAccelCal->
fvecA[j]) j = i;
402 det = pthisAccelCal->
fmatB[0][j] *
403 pthisAccelCal->
fmatB[1][j] *
404 pthisAccelCal->
fmatB[2][j];
407 for (i = 0; i < 7; i++)
409 pthisAccelCal->
fmatB[i][j] = -pthisAccelCal->
fmatB[i][j];
418 pthisAccelCal->
fV[
CHX] = -0.5F *
419 pthisAccelCal->
fmatB[3][j] /
420 pthisAccelCal->
fmatB[0][j];
421 pthisAccelCal->
fV[
CHY] = -0.5F *
422 pthisAccelCal->
fmatB[4][j] /
423 pthisAccelCal->
fmatB[1][j];
424 pthisAccelCal->
fV[
CHZ] = -0.5F *
425 pthisAccelCal->
fmatB[5][j] /
426 pthisAccelCal->
fmatB[2][j];
427 fg0 = sqrtf(fabsf(pthisAccelCal->
fmatB[0][j] * pthisAccelCal->
fV[
CHX] *
428 pthisAccelCal->
fV[
CHX] + pthisAccelCal->
fmatB[1][j] *
429 pthisAccelCal->
fV[
CHY] * pthisAccelCal->
fV[
CHY] +
430 pthisAccelCal->
fmatB[2][j] * pthisAccelCal->
fV[
CHZ] *
431 pthisAccelCal->
fV[
CHZ] - pthisAccelCal->
fmatB[6][j]));
457 for (i = 0; i < 10; i++)
458 for (j = i; j < 10; j++) pthisAccelCal->
fmatA[i][j] = 0.0F;
461 pthisAccelCal->
fvecA[9] = 1.0F;
473 pthisAccelCal->
fvecA[0] = pthisAccelCal->
fvecA[6] * pthisAccelCal->
fvecA[6];
474 pthisAccelCal->
fvecA[1] = 2.0F *
475 pthisAccelCal->
fvecA[6] *
476 pthisAccelCal->
fvecA[7];
477 pthisAccelCal->
fvecA[2] = 2.0F *
478 pthisAccelCal->
fvecA[6] *
479 pthisAccelCal->
fvecA[8];
480 pthisAccelCal->
fvecA[3] = pthisAccelCal->
fvecA[7] * pthisAccelCal->
fvecA[7];
481 pthisAccelCal->
fvecA[4] = 2.0F *
482 pthisAccelCal->
fvecA[7] *
483 pthisAccelCal->
fvecA[8];
484 pthisAccelCal->
fvecA[5] = pthisAccelCal->
fvecA[8] * pthisAccelCal->
fvecA[8];
487 for (m = 0; m < 10; m++)
489 for (n = m; n < 10; n++)
491 pthisAccelCal->
fmatA[m][n] += pthisAccelCal->
fvecA[m] * pthisAccelCal->
fvecA[n];
498 for (m = 1; m < 10; m++)
499 for (n = 0; n < m; n++)
500 pthisAccelCal->
fmatA[m][n] = pthisAccelCal->
fmatA[n][m];
504 pthisAccelCal->
fmatB, 10);
508 for (i = 1; i < 10; i++)
510 if (pthisAccelCal->
fvecA[i] < pthisAccelCal->
fvecA[j])
516 pthisAccelCal->
fA[0][0] = pthisAccelCal->
fmatB[0][j];
517 pthisAccelCal->
fA[0][1] = pthisAccelCal->
fA[1][0] = pthisAccelCal->
fmatB[1][j];
518 pthisAccelCal->
fA[0][2] = pthisAccelCal->
fA[2][0] = pthisAccelCal->
fmatB[2][j];
519 pthisAccelCal->
fA[1][1] = pthisAccelCal->
fmatB[3][j];
520 pthisAccelCal->
fA[1][2] = pthisAccelCal->
fA[2][1] = pthisAccelCal->
fmatB[4][j];
521 pthisAccelCal->
fA[2][2] = pthisAccelCal->
fmatB[5][j];
528 pthisAccelCal->
fmatB[6][j] = -pthisAccelCal->
fmatB[6][j];
529 pthisAccelCal->
fmatB[7][j] = -pthisAccelCal->
fmatB[7][j];
530 pthisAccelCal->
fmatB[8][j] = -pthisAccelCal->
fmatB[8][j];
531 pthisAccelCal->
fmatB[9][j] = -pthisAccelCal->
fmatB[9][j];
539 for (l =
CHX; l <=
CHZ; l++)
541 pthisAccelCal->
fV[l] = 0.0F;
542 for (m =
CHX; m <=
CHZ; m++)
544 pthisAccelCal->
fV[l] += pthisAccelCal->
finvA[l][m] * pthisAccelCal->
fmatB[m + 6][j];
547 pthisAccelCal->
fV[l] *= -0.5F;
551 fg0 = sqrtf(fabsf(pthisAccelCal->
fA[0][0] * pthisAccelCal->
fV[
CHX] *
552 pthisAccelCal->
fV[
CHX] + 2.0F * pthisAccelCal->
fA[0][1] *
553 pthisAccelCal->
fV[
CHX] * pthisAccelCal->
fV[
CHY] + 2.0F *
554 pthisAccelCal->
fA[0][2] * pthisAccelCal->
fV[
CHX] *
555 pthisAccelCal->
fV[
CHZ] + pthisAccelCal->
fA[1][1] *
556 pthisAccelCal->
fV[
CHY] * pthisAccelCal->
fV[
CHY] + 2.0F *
557 pthisAccelCal->
fA[1][2] * pthisAccelCal->
fV[
CHY] *
558 pthisAccelCal->
fV[
CHZ] + pthisAccelCal->
fA[2][2] *
559 pthisAccelCal->
fV[
CHZ] * pthisAccelCal->
fV[
CHZ] -
560 pthisAccelCal->
fmatB[9][j]));
565 for (i = 0; i < 3; i++)
566 for (j = 0; j < 3; j++)
567 pthisAccelCal->
fmatA[i][j] = pthisAccelCal->
fA[i][j];
569 pthisAccelCal->
fmatB, 3);
572 for (j = 0; j < 3; j++)
574 ftmp = sqrtf(sqrtf(fabsf(pthisAccelCal->
fvecA[j])));
575 for (i = 0; i < 3; i++)
577 pthisAccelCal->
fmatB[i][j] *= ftmp;
584 for (i = 0; i < 3; i++)
587 for (j = i; j < 3; j++)
589 pthisAccelCal->
finvW[i][j] = 0.0F;
592 for (k = 0; k < 3; k++)
594 pthisAccelCal->
finvW[i][j] += pthisAccelCal->
fmatB[i][k] * pthisAccelCal->
fmatB[j][k];
598 pthisAccelCal->
finvW[j][i] = pthisAccelCal->
finvW[i][j];
603 for (i =
CHX; i <=
CHZ; i++)
605 for (j =
CHX; j <=
CHZ; j++)
607 pthisAccelCal->
finvW[i][j] /= fg0;
void fmatrixAeqInvA(float *A[], int8 iColInd[], int8 iRowInd[], int8 iPivot[], int8 isize, int8 *pierror)
function uses Gauss-Jordan elimination to compute the inverse of matrix A in situ on exit...
int16_t iStoreLocation
-1 for none, 0 to 11 for the 12 storage locations
void fComputeAccelCalibration7(struct AccelBuffer *pthisAccelBuffer, struct AccelCalibration *pthisAccelCal, struct AccelSensor *pthisAccel)
calculate the 7 element calibration from the available measurements
#define CHY
Used to access Y-channel entries in various data data structures.
void f3DOFTiltNED(float fR[][3], float fGc[])
Aerospace NED accelerometer 3DOF tilt function, computing rotation matrix fR.
int16_t iStoreCounter
number of remaining iterations at FUSION_HZ to average measurement
Lower level sensor fusion interface.
void fComputeAccelCalibration4(struct AccelBuffer *pthisAccelBuffer, struct AccelCalibration *pthisAccelCal, struct AccelSensor *pthisAccel)
calculate the 4 element calibration from the available measurements
float fvecA[10]
scratch 10x1 vector used by calibration algorithms
float fvecB[4]
scratch 4x1 vector used by calibration algorithms
float fGsStored[MAX_ACCEL_CAL_ORIENTATIONS][3]
uncalibrated accelerometer measurements (g)
float fV[3]
offset vector (g)
void f3x3matrixAeqMinusA(float A[][3])
function negates all elements of 3x3 matrix A
#define ANDROID
identifier for Android axes and angles
int16_t iStoreFlags
denotes which measurements are present
float f3x3matrixDetA(float A[][3])
function calculates the determinant of a 3x3 matrix
int16_t iCountsPerg
counts per g
void fUpdateAccelBuffer(struct AccelCalibration *pthisAccelCal, struct AccelBuffer *pthisAccelBuffer, struct AccelSensor *pthisAccel, volatile int8 *AccelCalPacketOn)
Update the buffer used to store samples used for accelerometer calibration.
The AccelSensor structure stores raw and processed measurements for a 3-axis accelerometer.
void fComputeAccelCalibration10(struct AccelBuffer *pthisAccelBuffer, struct AccelCalibration *pthisAccelCal, struct AccelSensor *pthisAccel)
calculate the 10 element calibration from the available measurements
#define NED
identifier for NED (Aerospace) axes and angles
void fEigenCompute10(float A[][10], float eigval[], float eigvec[][10], int8 n)
function computes all eigenvalues and eigenvectors of a real symmetric matrix A[0..n-1][0..n-1] stored in the top left of a 10x10 array A[10][10]
void fRunAccelCalibration(struct AccelCalibration *pthisAccelCal, struct AccelBuffer *pthisAccelBuffer, struct AccelSensor *pthisAccel)
function runs the precision accelerometer calibration
float fGc[3]
averaged precision calibrated measurement (g)
The sensor_fusion.h file implements the top level programming interface.
void fVeq3x3AxV(float V[3], float A[][3])
function multiplies the 3x1 vector V by a 3x3 matrix A
void f3x3matrixAeqInvSymB(float A[][3], float B[][3])
function directly calculates the symmetric inverse of a symmetric 3x3 matrix only the on and above di...
float finvA[3][3]
inverse of the ellipsoid matrix A
#define WIN8
identifier for Windows 8 axes and angles
accelerometer measurement buffer
void f3DOFTiltAndroid(float fR[][3], float fGc[])
Android accelerometer 3DOF tilt function computing, rotation matrix fR.
#define MAX_ACCEL_CAL_ORIENTATIONS
number of stored precision accelerometer measurements
float fmatA[10][10]
scratch 10x10 matrix used by calibration algorithms
#define CHX
Used to access X-channel entries in various data data structures.
float fmatB[10][10]
scratch 10x10 matrix used by calibration algorithms
void f3x3matrixAeqI(float A[][3])
function sets the 3x3 matrix A to the identity matrix
int16_t iGc[3]
averaged precision calibrated measurement (counts)
float fR0[3][3]
forward rotation matrix for measurement 0
float fGs[3]
averaged measurement (g)
#define FUSION_HZ
(int) actual rate of fusion algorithm execution and sensor FIFO reads
void fInvertAccelCal(struct AccelSensor *pthisAccel, struct AccelCalibration *pthisAccelCal)
function maps the accelerometer data fGs (g) onto precision calibrated and de-rotated data fGc (g)...
void fInitializeAccelCalibration(struct AccelCalibration *pthisAccelCal, struct AccelBuffer *pthisAccelBuffer, volatile int8 *AccelCalPacketOn)
Initialize the accelerometer calibration functions.
float finvW[3][3]
inverse gain matrix
void f3x3matrixAeqScalar(float A[][3], float Scalar)
function sets every entry in the 3x3 matrix A to a constant scalar
float fSumGs[3]
averaging sum for current storage location
void f3DOFTiltWin8(float fR[][3], float fGc[])
Windows 8 accelerometer 3DOF tilt function computing, rotation matrix fR.
#define ACCEL_CAL_AVERAGING_SECS
calibration constants
precision accelerometer calibration structure
float fA[3][3]
ellipsoid matrix A